# frozen_string_literal: true

module Security
  module VulnerabilityScanning
    class FindingMap
      include Gitlab::Utils::StrongMemoize

      FINDING_ATTRIBUTES = %i[
        confidence
        metadata_version
        name
        raw_metadata
        report_type
        severity
        details
        description
        message
        cve
        solution
      ].freeze

      attr_reader :report_finding
      attr_accessor :finding_id, :vulnerability_id, :new_record, :identifier_ids, :scanner_id

      delegate :uuid, :severity, :evidence, to: :report_finding
      delegate :project_fingerprint, to: :report_finding, private: true

      def initialize(report_finding, scanner_id)
        @report_finding = report_finding
        @scanner_id = scanner_id
        @identifier_ids = []
      end

      def identifiers
        if report_finding.identifiers.count > Vulnerabilities::Finding::MAX_NUMBER_OF_IDENTIFIERS
          Gitlab::AppJsonLogger.warn(
            message: 'Finding exceeded max number of allowed identifiers - excess identifiers ignored',
            ignored_identifiers: report_finding.identifiers.drop(Vulnerabilities::Finding::MAX_NUMBER_OF_IDENTIFIERS)
          )
        end

        report_finding.identifiers.first(Vulnerabilities::Finding::MAX_NUMBER_OF_IDENTIFIERS)
      end
      strong_memoize_attr :identifiers

      def set_identifier_ids_by(fingerprint_id_map)
        @identifier_ids = identifiers.map { |identifier| fingerprint_id_map[identifier.fingerprint] }
      end

      def to_hash
        report_finding.to_hash
                      .slice(*FINDING_ATTRIBUTES)
                      .merge!(
                        uuid: uuid,
                        scanner_id: scanner_id,
                        project_fingerprint: project_fingerprint,
                        primary_identifier_id: identifier_ids.first,
                        location: report_finding.location_data,
                        location_fingerprint: report_finding.location_fingerprint
                      )
      end
    end
  end
end
